home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-12-14 | 40.8 KB | 2,275 lines |
- Newsgroups: comp.sources.misc
- From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- Subject: v09i066: browse: screen-oriented directory browser
- Reply-To: peter@ficc.UUCP (Peter Da Silva)
-
- Posting-number: Volume 9, Issue 66
- Submitted-by: peter@ficc.UUCP (Peter Da Silva)
- Archive-name: browse_pds
-
- :
- #! /bin/sh
- # This is a shell archive, created at Ferranti International Controls Corp.
- # by peter (peter da silva,2810T 5180 @xds13) on Fri Nov 10 16:15:15 1989
- # Remove anything before the "#! /bin/sh" line, then unpack it by saving
- # it into a file and typing "sh file". If you do not have sh, you need
- # unshar, a dearchiving program which is widely available. In the absolute
- # wost case, you can crack the files out by hand.
- # If the archive is complete, you will see the message "End of archive."
- # at the end.
- # This archive contains the following files...
- # 'Makefile'
- # 'browse.doc'
- # 'browse.c'
- # To extract them, run the following through /bin/sh
- echo x - Makefile
- sed 's/^X//' > Makefile << '//END_OF_FILE'
- XCFILES=browse.c
- XOFILES=$(CFILES:.c=.o)
- XTFILES=Makefile browse.doc $(CFILES)
- XCFLAGS=-O
- XLFLAGS=-O
- XLIBS=-ltermlib
- X
- Xbrowse: $(OFILES)
- X $(CC) $(LFLAGS) $(OFILES) -o browse $(LIBS)
- X
- Xbrowse.shar: $(TFILES)
- X shar $(TFILES) > browse.shar
- //END_OF_FILE
- echo x - browse.doc
- sed 's/^X//' > browse.doc << '//END_OF_FILE'
- XBrowse is a screen-oriented directory browser, based on the metaphor of using
- X'VI' to edit an 'ls -l' listing.
- X
- XCommands:
- X SPACE Enter a subdirectory, or display a file.
- X & Run a program that won't clobber the screen.
- X ! Run a program.
- X = Enter a directory name.
- X ? Peek at the current file.
- X [ Define a macro.
- X H Go to the top of the page.
- X J Go to the bottom of the directory.
- X K Go to the top of the directory.
- X L Go to the bottom of the page.
- X ^L Repaint screen.
- X M Display macros.
- X N,^F Go down 20 lines.
- X P,^B Go up 20 lines.
- X R Rename a file.
- X S Save definitions.
- X dd Delete file(s). (ask for verification)
- X DD Delete file(s).
- X h Place cursor at beginning of line.
- X l Move cursor to end of line.
- X < Display file names only.
- X > Display long directory listing.
- X + Make a file permanent.
- X ( Make the current file permanent.
- X ) Make the current file non-permanent.
- X j,^J Go down a line.
- X k,^K Go up a line.
- X n,^D Go down 11 lines.
- X p,^U Go up 11 lines.
- X
- X qq,QQ,ZZ Exit.
- X
- X r Re-read directories.
- X
- X t Toggle tag on current file.
- X T Tag all files.
- X U Untag all files.
- X
- XMacros:
- X [xtext] Define x as text.
- X
- XWithin text:
- X % Current filename.
- X # Current directory.
- X ! Previous command.
- X $x Macro for key x
- X $$ Current process ID
- X ~ Home directory.
- X ^K One character from previous command.
- X @x Execute macro for key x
- X \x Enter special character x
- X \nnn nnn, octal
- X \^x Control-x
- X
- XDefault macros:
- X SPACE !more %<CR>
- X % !%<CR>
- X . =.
- X / =/
- X ~ =~
- X v !vi %<CR>
- X $ !vi /tmp/br.env.$$<CR>
- X -- this file is loaded as your environment
- X -- whenever you run a program.
- X
- XThe contents of the environment variable BROWSE are executed as a macro
- Xwhen you start up.
- //END_OF_FILE
- echo x - browse.c
- sed 's/^X//' > browse.c << '//END_OF_FILE'
- X/* -- Just what the hell am I ??? --- */
- X
- X#include <stdio.h>
- X#ifdef M_XENIX
- X#define USG
- X#define rindex strrchr
- X#define GETCWD
- X#else
- X#ifdef L_ctermid
- X#define USG
- X#define rindex strrchr
- X#define minor(i) ((i)&0xFF)
- X#define major(i) minor((i)>>8)
- X#else
- X#include <whoami.h>
- X#endif
- X#endif
- X
- X/* -- Miscellaneous include files -- */
- X
- X#include <sys/param.h> /* NCARGS, and others */
- X#ifndef M_XENIX
- X#include <sys/types.h> /* data types for various files */
- X#endif
- X#include <sys/stat.h> /* stat data structure for getdir(), statout() */
- X#include <sys/dir.h> /* dir data structure for getdir() */
- X#include <pwd.h> /* passwd data structure for u_name() */
- X#include <grp.h> /* group data structure for g_name() */
- X#ifdef BSD
- X#include <sys/time.h> /* time data structure for printime() */
- X#else
- X#include <time.h> /* time data structure for printime() */
- X#endif
- X#ifdef USG
- X#ifdef M_XENIX
- X#include <sys/ioctl.h>
- X#endif
- X#include <termio.h>
- X#else
- X#include <sgtty.h> /* terminal modes for tinit(), tend() */
- X#endif
- X#include <signal.h>
- X
- X/* -- make information --
- XBUILD
- Xbrowse: browse.c
- X cc browse.c -O -o browse -ltermlib
- XEND
- X*/
- X
- X/* -- Miscellaneous defines -- */
- X#define FALSE 0
- X#define TRUE 1
- X
- X#define MAXENTS 320
- X#define MAXID 16
- X#define MAXLINE 81
- X#define NCOL 64
- X#define MAXNAME 14
- X#define FILENAME 256
- X#define MAXARGC (NCARGS/16) /* Estimate max ARGC */
- X#define CHARSET 256 /* Number of macros == size of byte */
- X#define NOMAC (0) /* Null macro (last) */
- X#define TERMBUF 1024 /* Size of term buf for termcap */
- X#define SMALLBUF 256
- X
- X/* -- Extended directory entry format -- */
- Xstruct entry {
- X char *e_name;
- X int e_flags;
- X#define FTAGGED (1<<0)
- X#define FPERMANENT (1<<1)
- X struct stat e_stat; /* file status field */
- X char e_uname[9]; /* user name */
- X char e_gname[9]; /* user's group name */
- X}
- X*xentries[MAXENTS], **entries=xentries;
- Xint nentries;
- X
- X/* -- Look-up cache for user names -- */
- Xstruct idtab {
- X int id_id; /* user (or group) id */
- X char id_name[9]; /* name[8] + filler */
- X}
- Xu_list[MAXID], /* Matched user id's. */
- Xg_list[MAXID]; /* ditto group */
- Xint u_ptr=0, g_ptr=0; /* current entries */
- X
- X/* -- Global variables -- */
- XFILE *efp; /* Environment file */
- Xchar efname[MAXLINE]; /* " name */
- Xchar *tent; /* Pointer to tbuf */
- Xchar PC; /* Pad character */
- Xchar *UP, *BC; /* Upline, backsapce character */
- Xshort ospeed; /* Terminal output speed */
- Xchar termbuf[TERMBUF]; /* Place to put term info */
- X
- Xchar *macbuf[CHARSET], ungetbuf[SMALLBUF]; /* Buffers for pushback and macros */
- Xchar c_macro=NOMAC; /* current macro */
- Xchar *macptr = ""; /* Pointer to currently executing macro */
- Xchar *ungetptr = ungetbuf; /* Pointer to pushed-back characters */
- X
- Xchar *errname; /* Name of file error found in */
- Xextern int errno; /* system error number */
- Xint xerrno; /* extended error number */
- Xint ccol=NCOL; /* Width of used display, current column */
- Xint quickmode; /* short display mode (files only) */
- X
- X#ifdef USG
- Xstruct termio rawbuf;
- Xstruct termio cookedbuf;
- X#else
- Xstruct sgttyb sgbuf; /* buffer for terminal mode info */
- Xint rawflags, cookflags; /* flags for raw & cooked tty mode */
- X#endif
- X
- Xchar *cm, /* Cursor motion */
- X *cs, /* Change scrolling region */
- X *sf, /* - scroll forward */
- X *sr, /* - scroll backwards */
- X *ce, /* Clear to end of line */
- X *cl, /* Clear screen */
- X *al, /* Insert line */
- X *dl, /* delete ditto */
- X *so, /* standout */
- X *se, /* standout end */
- X *us, /* underline */
- X *ue, /* underline end */
- X *ti, /* Init terminal */
- X *te; /* Reset terminal */
- Xint li, /* lines on screen */
- X co; /* columns ditto */
- Xchar xn; /* Magic cookie kludge */
- X
- X/* -- Global error messages -- */
- Xchar *emesg[4]={
- X "??",
- X#define TOO_MANY 1
- X "Too many directory entries",
- X#define NOMATCH 2
- X "No match",
- X 0
- X};
- X
- Xint top, curr; /* Positions of screen in directory */
- X#define bottom ((top+nlines>nentries)?nentries:(top+nlines))
- Xchar *dot; /* name of current directory */
- Xint nlines; /* number of lines displayed on page */
- Xchar display_up; /* Does the display exist? */
- Xint todump=1; /* Do we want to dump data? */
- Xint ended; /* Have we quite finished? */
- Xint intrup; /* Have we been interrupted? */
- Xchar *HOME; /* Where did I start from? */
- Xchar *SHELL; /* How do I run programs? */
- X
- X/* -- types of functions !!! */
- Xchar *getenv(), *tgetstr();
- Xchar *malloc();
- X
- X#define NEW(t) (t *)malloc(sizeof (t))
- X#define NIL(t) ((t) 0)
- X
- X/* -- Code starts here: dummy main -- */
- Xmain(ac, av, ep)
- Xint ac;
- Xchar **av;
- Xchar **ep;
- X{
- X if(ac>1) chdir(av[1]);
- X
- X sprintf(efname, "/tmp/br.env.%d", getpid());
- X HOME=getenv("HOME");
- X SHELL=getenv("SHELL");
- X dumpenv(ep);
- X
- X intrup=0;
- X tinit(getenv("TERM"));
- X clear_all();
- X browse();
- X tend();
- X unlink(efname);
- X}
- X
- Xclear_all()
- X{
- X int i;
- X
- X for(i = 0; i < MAXENTS; i++)
- X entries[i] = 0;
- X}
- X
- Xchar *clone(name)
- Xchar *name;
- X{
- X char *hold;
- X
- X hold = (char *)malloc(strlen(name)+1);
- X
- X if(hold==0)
- X return 0;
- X strcpy(hold, name);
- X return hold;
- X}
- X
- Xnewname(e, name)
- Xstruct entry *e;
- Xchar *name;
- X{
- X if(e->e_name)
- X free(e->e_name);
- X e->e_name = clone(name);
- X}
- X
- X#if BSD
- Xreadent(dp, db)
- XDIR *dp;
- Xstruct direct *db;
- X{
- X struct direct *ptr;
- X
- X ptr = readdir(dp);
- X if(!ptr) return 0;
- X
- X *db = *ptr; /* V7 'C' and above... safe, since UCB=V7+ */
- X free(ptr);
- X return 1;
- X}
- X#else
- X#define opendir(n) fopen(n, "r")
- X#define DIR FILE
- Xreadent(dp, db)
- XDIR *dp;
- Xstruct direct *db;
- X{
- X if(fread(db, sizeof(struct direct), 1, dp))
- X return 1;
- X /* else */
- X return 0;
- X}
- X#define closedir fclose
- X#endif
- X
- Xgetdir()
- X{
- X char *u_name(), *g_name();
- X DIR *dp;
- X int valid;
- X struct direct *hold = NEW(struct direct);
- X int i, p;
- X
- X if(!(dp = opendir("."))) {
- X errname=".";
- X return FALSE;
- X }
- X
- X p = 0;
- X for(i = 0; i < nentries; i++) {
- X if(entries[i]->e_flags & FPERMANENT) {
- X if(p != i) {
- X struct entry *hold;
- X hold = entries[p];
- X entries[p] = entries[i];
- X entries[i] = hold;
- X }
- X p++;
- X }
- X }
- X
- X for(nentries = p; !intrup && nentries < MAXENTS; nentries += valid) {
- X
- X if(!entries[nentries]) {
- X entries[nentries] = NEW(struct entry);
- X if(!entries[nentries])
- X break;
- X entries[nentries]->e_name = NIL(char *);
- X }
- X
- X if(!readent(dp, hold))
- X break;
- X
- X valid = (hold->d_ino != 0);
- X if(valid) {
- X if(stat(hold->d_name, &entries[nentries]->e_stat)==-1) {
- X closedir(dp);
- X errname=hold->d_name;
- X free(hold);
- X return FALSE;
- X }
- X
- X newname(entries[nentries], hold->d_name);
- X
- X#ifndef BSD /* truncate name to 14 characters in non-BSD systems */
- X if(strlen(entries[nentries]->e_name)>14)
- X entries[nentries]->e_name[14] = 0;
- X#endif
- X
- X entries[nentries]->e_flags = 0;
- X
- X strcpy(entries[nentries]->e_uname,
- X u_name(entries[nentries]->e_stat.st_uid));
- X
- X strcpy(entries[nentries]->e_gname,
- X g_name(entries[nentries]->e_stat.st_gid));
- X }
- X }
- X
- X closedir(dp);
- X
- X free(hold);
- X
- X if(intrup)
- X return FALSE;
- X
- X if(nentries>=MAXENTS || entries[nentries]==NIL(struct entry *)) {
- X errno=0;
- X xerrno=TOO_MANY;
- X errname=".";
- X return FALSE;
- X }
- X
- X sortdir();
- X
- X if(intrup)
- X return FALSE;
- X return TRUE;
- X}
- X
- Xat_current()
- X{
- X at_file(curr);
- X}
- X
- Xat_file(file)
- Xint file;
- X{
- X if(display_up) {
- X if(file < top || file >= top+nlines)
- X return 0;
- X at(0, curr-top+2);
- X } else {
- X if(file != curr)
- X return 0;
- X cmdline();
- X }
- X return 1;
- X}
- X
- Xdisplay_flags(flags)
- X{
- X outc((flags&FTAGGED)?'+':((flags&FPERMANENT)?'!':' '));
- X}
- X
- Xrepaint_flags()
- X{
- X if(!display_up) return;
- X at(NCOL-1, curr-top+2);
- X display_flags(entries[curr]->e_flags);
- X}
- X
- Xrepaint_current()
- X{
- X if(!display_up) return;
- X at_current();
- X dump(curr, curr+1);
- X}
- X
- Xtag()
- X{
- X entries[curr]->e_flags ^= FTAGGED;
- X repaint_flags();
- X}
- X
- Xtag_all(flag)
- Xint flag;
- X{
- X int i;
- X
- X for(i = 0; i < nentries; i++)
- X if(flag)
- X entries[i]->e_flags |= FTAGGED;
- X else
- X entries[i]->e_flags &= ~FTAGGED;
- X if(display_up)
- X todump = TRUE;
- X}
- X
- Xdelete_from_display(file)
- Xint file;
- X{
- X if(!display_up) return;
- X
- X if(file>=top+nlines) return;
- X
- X if(file < top) file = top;
- X
- X scroll(2+file-top, 2+nlines, 1);
- X at(0, 2+nlines-1);
- X if(top+nlines >= nentries)
- X outc('~');
- X else
- X dump(bottom, bottom+1);
- X}
- X
- Xdelete_file_entry(file)
- Xint file;
- X{
- X struct entry *hold;
- X int i;
- X
- X delete_from_display(file);
- X
- X hold = entries[file];
- X for(i=file; i<nentries-1; i++)
- X entries[i]=entries[i+1];
- X entries[nentries-1]=hold;
- X nentries--;
- X
- X if(file < curr || curr >= nentries) {
- X curr--;
- X if(top >= nentries) {
- X top--;
- X display_up = 0;
- X todump = 1;
- X }
- X }
- X}
- X
- Xremove_one(file, doit)
- Xint file;
- Xint doit;
- X{
- X if(!doit) {
- X cmdline();
- X outs("Delete ");
- X ctlouts(entries[file]->e_name);
- X outs(" [n]?");
- X doit = getchar() == 'y';
- X outs(doit?"Yes.":"No.");
- X }
- X if(doit) {
- X if(unlink(entries[file]->e_name) == 0) {
- X cmdline();
- X outs("Deleted ");
- X ctlouts(entries[file]->e_name);
- X outs(".");
- X delete_file_entry(file);
- X return 1;
- X } else {
- X wperror(entries[file]->e_name);
- X return 0;
- X }
- X }
- X return 0;
- X}
- X
- Xremove(doit)
- Xint doit;
- X{
- X int i;
- X int found_tags;
- X
- X found_tags = 0;
- X i = 0;
- X while(i < nentries) {
- X if(entries[i]->e_flags & FTAGGED) {
- X found_tags = 1;
- X if(!remove_one(i, doit)) /* decrements nentries */
- X break;
- X } else
- X i++;
- X }
- X if(!found_tags)
- X remove_one(curr, doit);
- X}
- X
- Xinsert_entry_at(ent, i)
- Xstruct entry *ent;
- Xint i;
- X{
- X struct entry *hold;
- X int j;
- X
- X /* Allocate slot at end */
- X if(!entries[nentries]) {
- X entries[nentries] = NEW(struct entry);
- X if(!entries[nentries])
- X return 0;
- X entries[nentries]->e_name = NIL(char *);
- X } else if(entries[nentries]->e_name) {
- X free(entries[nentries]->e_name);
- X entries[nentries]->e_name = NIL(char *);
- X }
- X
- X /* Copy data into slot */
- X *entries[nentries] = *ent;
- X entries[nentries]->e_name = clone(ent->e_name);
- X if(!entries[nentries]->e_name)
- X return 0;
- X
- X if(i != nentries) {
- X /* Rotate slot to middle */
- X hold = entries[nentries];
- X for(j = nentries; j > i; j--)
- X entries[j] = entries[j-1];
- X entries[i] = hold;
- X }
- X nentries++;
- X
- X if(display_up) {
- X if(i < top)
- X i = top;
- X if(i >= bottom)
- X return;
- X scroll(2+i-top, 2+nlines, -1);
- X at(0, 2+i-top);
- X dump(i, i+1);
- X }
- X}
- X
- Xinsert_entry(ent)
- Xstruct entry *ent;
- X{
- X int i;
- X
- X if(nentries >= MAXENTS)
- X return 0;
- X
- X for(i = 0; i < nentries; i++)
- X if(entcmp(&ent, &entries[i]) < 0)
- X break;
- X
- X return insert_entry_at(ent, i);
- X}
- X
- Xmove()
- X{
- X char scratch[FILENAME];
- X struct entry hold;
- X char inps();
- X
- X hold = *entries[curr];
- X
- X cmdline();
- X outs("Rename ");
- X ctlouts(entries[curr]->e_name);
- X outc(' ');
- X if(inps(scratch, entries[curr]->e_name, 0)=='\033') {
- X killcmd();
- X return;
- X }
- X if(link(entries[curr]->e_name, scratch)!=0) {
- X char tmbuf[42];
- X sprintf(tmbuf, "(rename %s %s)", entries[curr]->e_name, scratch);
- X wperror(tmbuf);
- X return;
- X }
- X if(unlink(entries[curr]->e_name)!=0) {
- X wperror(entries[curr]->e_name);
- X return;
- X }
- X
- X hold.e_name = scratch;
- X hold.e_flags &= ~FTAGGED;
- X
- X delete_file_entry(curr);
- X insert_entry(&hold);
- X}
- X
- Xpname(name, mode)
- Xchar *name;
- Xint mode;
- X{
- X int i;
- X char *slash, *rindex();
- X int max=quickmode?MAXLINE:(MAXNAME+1);
- X
- X if((mode&S_IFMT)==S_IFDIR)
- X max--;
- X else if((mode&S_IFMT)==S_IFREG && (mode&0111))
- X max--;
- X else if((mode&S_IFMT)!=S_IFREG)
- X max--;
- X
- X if(!quickmode && (slash=rindex(name, '/'))) {
- X name=slash;
- X outc('<');
- X max--;
- X }
- X for(i=0; i<max && *name; name++)
- X i += ctlout(*name);
- X standend();
- X if(i==max && *name)
- X outs("\b>");
- X if((mode&S_IFMT)==S_IFDIR) {
- X outc('/');
- X }
- X else if((mode&S_IFMT)==S_IFREG && (mode&0111)) {
- X outc('*');
- X }
- X else if((mode&S_IFMT)!=S_IFREG) {
- X outc('?');
- X }
- X}
- X
- Xsortdir()
- X{
- X int entcmp();
- X qsort(entries, nentries, sizeof(struct entry *), entcmp);
- X}
- X
- Xaddname(flag)
- Xchar flag;
- X{
- X char buf[FILENAME], *ptr, *tmp;
- X char scratch[FILENAME];
- X struct entry hold;
- X char inps();
- X
- X cmdline();
- X outs("Add ");
- X if(inps(scratch, entries[curr]->e_name, 0)=='\033') {
- X killcmd();
- X return;
- X }
- X
- X if(stat(scratch, &hold.e_stat)==-1) {
- X wperror(scratch);
- X return;
- X }
- X if(flag!='+' && *scratch != '/') {
- X strcpy(buf, dot);
- X ptr = scratch;
- X for(;;) { /* eat '../' and './' */
- X if(ptr[0]=='.' && ptr[1]=='.' &&
- X (ptr[2]=='/' || !ptr[2])) {
- X tmp = rindex(buf, '/');
- X if(!tmp) break;
- X *tmp=0;
- X ptr += 2+(ptr[2]=='/');
- X continue;
- X }
- X if(ptr[0]=='.' &&
- X (ptr[1]=='/' || !ptr[1])) {
- X ptr += 1+(ptr[1]=='/');
- X continue;
- X }
- X break;
- X }
- X if(*ptr) {
- X strcat(buf, "/");
- X strcat(buf, ptr);
- X }
- X hold.e_name = buf;
- X } else
- X hold.e_name = scratch;
- X strcpy(hold.e_uname,
- X u_name(hold.e_stat.st_uid));
- X strcpy(hold.e_gname,
- X g_name(hold.e_stat.st_gid));
- X hold.e_flags = 0;
- X if(flag!='+')
- X hold.e_flags |= FPERMANENT;
- X insert_entry(&hold);
- X}
- X
- Xaddperm()
- X{
- X char buf[FILENAME], *ptr, *tmp;
- X struct entry hold;
- X int entcmp(), i;
- X
- X if(entries[curr]->e_flags & FPERMANENT)
- X return;
- X
- X if(entries[curr]->e_name[0]!='/') {
- X strcpy(buf, dot);
- X ptr = entries[curr]->e_name;
- X for(;;) { /* eat '../' and './' */
- X if(ptr[0]=='.' && ptr[1]=='.' &&
- X (ptr[2]=='/' || !ptr[2])) {
- X tmp = rindex(buf, '/');
- X if(!tmp) break;
- X *tmp=0;
- X ptr += 2+(ptr[2]=='/');
- X continue;
- X }
- X if(ptr[0]=='.' &&
- X (ptr[1]=='/' || !ptr[1])) {
- X ptr += 1+(ptr[1]=='/');
- X continue;
- X }
- X break;
- X }
- X if(*ptr) {
- X strcat(buf, "/");
- X strcat(buf, ptr);
- X }
- X hold = *entries[curr];
- X
- X hold.e_name = buf;
- X hold.e_flags &= ~FTAGGED;
- X hold.e_flags |= FPERMANENT;
- X insert_entry(&hold);
- X } else {
- X entries[curr]->e_flags |= FPERMANENT;
- X entries[curr]->e_flags &= ~FTAGGED;
- X repaint_flags();
- X }
- X}
- X
- Xdelperm()
- X{
- X entries[curr]->e_flags &= ~(FPERMANENT|FTAGGED);
- X repaint_flags();
- X}
- X
- Xentcmp(e1, e2)
- Xstruct entry **e1, **e2;
- X{
- X if((*e1)->e_name[0] == '/') {
- X if((*e2)->e_name[0] != '/')
- X return 1;
- X } else if((*e2)->e_name[0] == '/')
- X return -1;
- X
- X return strcmp((*e1)->e_name, (*e2)->e_name);
- X}
- X
- Xdump(start, end)
- Xint start;
- Xint end;
- X{
- X int i;
- X int lo = (start<nentries)?start:nentries;
- X int hi = (end<nentries)?end:nentries;
- X
- X for(i=lo; i<hi; i++) {
- X statout(entries[i]->e_name,
- X &entries[i]->e_stat,
- X entries[i]->e_uname,
- X entries[i]->e_gname,
- X entries[i]->e_flags);
- X nl();
- X }
- X return TRUE;
- X}
- X
- Xstatout(name, sbuf, user, group, flags)
- Xchar *name;
- Xstruct stat *sbuf;
- Xchar *user, *group;
- Xint flags;
- X{
- X int mode = sbuf->st_mode;
- X
- X if(!quickmode) {
- X printf("%5u ", sbuf->st_ino);
- X
- X if((mode&S_IFMT)==S_IFCHR) outc('c');
- X else if((mode&S_IFMT)==S_IFBLK) outc('b');
- X else if((mode&S_IFMT)==S_IFDIR) outc('d');
- X else if((mode&S_IFMT)==S_IFREG) outc('-');
- X else outc('?');
- X triad((mode>>6)&7, mode&S_ISUID, 's');
- X triad((mode>>3)&7, mode&S_ISGID, 's');
- X triad(mode&7, mode&S_ISVTX, 't');
- X outc(' ');
- X
- X printf("%3u ", sbuf->st_nlink);
- X printf("%-8s ", user);
- X printf("%-8s ", group);
- X
- X if((mode&S_IFMT)==S_IFREG || (mode&S_IFMT)==S_IFDIR)
- X printf("%7ld ", sbuf->st_size);
- X else
- X printf("%3d,%3d ",
- X major(sbuf->st_rdev),
- X minor(sbuf->st_rdev));
- X
- X outc(' ');
- X printime(&sbuf->st_mtime);
- X }
- X
- X display_flags(flags);
- X pname(name, sbuf->st_mode);
- X}
- X
- Xchar *
- Xu_name(uid)
- Xint uid;
- X{
- X int i;
- X struct passwd *pwptr, *getpwuid();
- X
- X for(i=0; i<u_ptr; i++)
- X if(u_list[i].id_id==uid)
- X return u_list[i].id_name;
- X
- X if(u_ptr>=MAXID) /* cache full */
- X u_ptr = 0; /* simplistic algorithm, wrap to beginning */
- X /* with MAXID >> # common id's it's good enough */
- X
- X u_list[u_ptr].id_id=uid;
- X
- X if(pwptr=getpwuid(uid)) { /* Copy name */
- X for(i=0; pwptr->pw_name[i]>' '; i++)
- X u_list[u_ptr].id_name[i]=pwptr->pw_name[i];
- X u_list[u_ptr].id_name[i]=0;
- X }
- X else /* Default to UID */
- X sprintf(u_list[u_ptr].id_name, "%d", uid);
- X
- X return u_list[u_ptr++].id_name;
- X}
- X
- Xchar *
- Xg_name(gid)
- Xint gid;
- X{
- X int i;
- X struct group *grptr, *getgrgid();
- X
- X for(i=0; i<g_ptr; i++)
- X if(g_list[i].id_id==gid)
- X return g_list[i].id_name;
- X
- X if(g_ptr>=MAXID) /* cache full */
- X g_ptr = 0; /* simplistic algorithm, wrap to beginning */
- X /* with MAXID >> # common id's it's good enough */
- X
- X g_list[g_ptr].id_id=gid;
- X
- X if(grptr=getgrgid(gid)) { /* Copy name */
- X for(i=0; grptr->gr_name[i]>' '; i++)
- X g_list[g_ptr].id_name[i]=grptr->gr_name[i];
- X g_list[g_ptr].id_name[i]=0;
- X }
- X else /* Default to UID */
- X sprintf(g_list[g_ptr].id_name, "%d", gid);
- X
- X return g_list[g_ptr++].id_name;
- X}
- X
- Xprintime(clock)
- Xlong *clock;
- X{
- X struct tm *tmbuf, *localtime();
- X static char *months[12]= {
- X "Jan","Feb","Mar","Apr","May","Jun",
- X "Jul","Aug","Sep","Oct","Nov","Dec"
- X };
- X
- X tmbuf=localtime(clock);
- X printf("%2d %3s %02d %2d:%02d",
- X tmbuf->tm_mday,
- X months[tmbuf->tm_mon],
- X tmbuf->tm_year,
- X tmbuf->tm_hour,
- X tmbuf->tm_min);
- X}
- X
- Xheader()
- X{
- X int i;
- X if(quickmode)
- X printf(" File Name");
- X else
- X printf(
- X"Inode Long mode LNX User Group Size/Dev Modify Time File name"
- X );
- X nl();
- X}
- X
- Xtriad(bits, special, code)
- Xint bits, special;
- Xchar code;
- X{
- X if(bits&4) outc('r');
- X else outc('-');
- X
- X if(bits&2) outc('w');
- X else outc('-');
- X
- X if(special) outc(code);
- X else if(bits&1) outc('x');
- X else outc('-');
- X}
- X
- Xouts(s)
- Xchar *s;
- X{
- X int outc();
- X
- X if(s)
- X tputs(s, 0, outc);
- X}
- X
- Xoutc(c)
- Xchar c;
- X{
- X putchar(c);
- X}
- X
- X/* Screen manipulation primitives: dumb set for smart terminals */
- Xat(x, y)
- Xint x, y;
- X{
- X outs(tgoto(cm, x, y));
- X}
- X
- Xnl()
- X{
- X outs(ce);
- X outc('\n');
- X}
- X
- X
- X/* Scroll lines in window (from:to) n lines */
- Xscroll(from, to, n)
- Xint from, to, n;
- X{
- X if(cs && sf && sr) {
- X outs(tgoto(cs, from, to-1));
- X if(n<0)
- X while(n++)
- X outs(sr);
- X else
- X while(n--)
- X outs(sf);
- X outs(tgoto(cs, 0, li-1));
- X }
- X else if(al && dl) {
- X if(n<0) {
- X int i=n;
- X outs(tgoto(cm, 0, to+n));
- X while(i++)
- X outs(dl);
- X outs(tgoto(cm, 0, from));
- X while(n++)
- X outs(al);
- X }
- X else {
- X int i=n;
- X outs(tgoto(cm, 0, from));
- X while(i--)
- X outs(dl);
- X outs(tgoto(cm, 0, to-n));
- X while(n--)
- X outs(al);
- X }
- X }
- X}
- X
- Xwperror(file)
- Xchar *file;
- X{
- X extern int errno;
- X extern char *sys_errlist[];
- X
- X cmdline();
- X ctlouts(file);
- X ctlouts(": ");
- X ctlouts(errno?sys_errlist[errno]:emesg[xerrno]);
- X if(!display_up)
- X nl();
- X}
- X
- Xfperror(prog, file)
- Xchar *prog, *file;
- X{
- X extern int errno;
- X
- X fprintf(stderr, "%s -- ", prog);
- X if(errno)
- X perror(file);
- X else
- X fprintf(stderr, "%s: %s\n", file, emesg[xerrno]);
- X}
- X
- Xtinit(name)
- Xchar *name;
- X{
- X char *termptr;
- X char tbuf[TERMBUF], *tmp;
- X int intr();
- X#ifdef BSD
- X int stop();
- X#endif
- X
- X termptr = termbuf;
- X
- X tgetent(tbuf, name);
- X
- X tmp = tgetstr("pc", &termptr);
- X if(tmp) PC = *tmp;
- X UP = tgetstr("up", &termptr);
- X BC = tgetstr("bc", &termptr);
- X cm = tgetstr("cm", &termptr);
- X cs = tgetstr("cs", &termptr);
- X sf = tgetstr("sf", &termptr);
- X sr = tgetstr("sr", &termptr);
- X ce = tgetstr("ce", &termptr);
- X cl = tgetstr("cl", &termptr);
- X al = tgetstr("al", &termptr);
- X dl = tgetstr("dl", &termptr);
- X us = tgetstr("us", &termptr);
- X ue = tgetstr("ue", &termptr);
- X so = tgetstr("so", &termptr);
- X se = tgetstr("se", &termptr);
- X ti = tgetstr("ti", &termptr);
- X te = tgetstr("te", &termptr);
- X li = tgetnum("li");
- X co = tgetnum("co");
- X xn = tgetflag("xn");
- X
- X nlines=li-3;
- X
- X#ifdef USG
- X ioctl(1, TCGETA, &rawbuf);
- X cookedbuf = rawbuf;
- X rawbuf.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
- X rawbuf.c_cc[VMIN] = 1;
- X rawbuf.c_cc[VTIME] = 0;
- X#else
- X gtty(1, &sgbuf);
- X ospeed=sgbuf.sg_ospeed;
- X quickmode=ospeed<10;
- X cookflags=sgbuf.sg_flags;
- X sgbuf.sg_flags = (sgbuf.sg_flags&~ECHO)|CBREAK;
- X rawflags=sgbuf.sg_flags;
- X#endif
- X signal(SIGINT, intr);
- X#ifdef BSD
- X signal(SIGTSTP, stop);
- X#endif
- X rawtty();
- X}
- X
- Xint tmode=0;
- X
- Xentty()
- X{
- X if(!tmode)
- X outs(ti);
- X tmode=1;
- X}
- X
- Xextty()
- X{
- X if(tmode)
- X outs(te);
- X tmode=0;
- X}
- X
- Xrawtty()
- X{
- X#ifdef USG
- X ioctl(1, TCSETA, &rawbuf);
- X#else
- X sgbuf.sg_flags=rawflags;
- X stty(1, &sgbuf);
- X#endif
- X entty();
- X}
- X
- Xcooktty()
- X{
- X#ifdef USG
- X ioctl(1, TCSETA, &cookedbuf);
- X#else
- X sgbuf.sg_flags=cookflags;
- X stty(1, &sgbuf);
- X#endif
- X extty();
- X}
- X
- Xintr()
- X{
- X int intr();
- X signal(SIGINT, intr);
- X intrup=1;
- X bell();
- X}
- X
- X#ifdef BSD
- Xstop()
- X{
- X int stop();
- X signal(SIGTSTP, stop);
- X intrup=1;
- X tend();
- X kill(getpid(), SIGSTOP);
- X rawtty();
- X display_up=0;
- X}
- X#endif
- X
- Xtend()
- X{
- X cmdline();
- X cooktty();
- X fflush(stdout);
- X}
- X
- Xchar *
- Xpwd()
- X#ifdef GETCWD
- X{
- X static char mydir[FILENAME+1] = "";
- X char *getcwd();
- X
- X return getcwd(mydir, FILENAME);
- X}
- X#else
- X{
- X static char mydir[FILENAME] = "";
- X int status;
- X int pip[2];
- X int n;
- X int (*sigs[2])();
- X
- X sigs[0] = signal(2, 1);
- X sigs[1] = signal(3, 1);
- X
- X if(pipe(pip)<0)
- X return 0;
- X
- X if(!fork()) {
- X close(1);
- X dup(pip[1]);
- X close(pip[0]);
- X execl("/bin/pwd", "pwd", 0);
- X exit(-1);
- X }
- X close(pip[1]);
- X wait(&status);
- X signal(2, sigs[0]);
- X signal(3, sigs[1]);
- X
- X if(status) {
- X close(pip[0]);
- X return "/";
- X }
- X n = read(pip[0], mydir, FILENAME);
- X close(pip[0]);
- X if(n<=0)
- X return "/";
- X mydir[n-1] = 0;
- X return mydir;
- X}
- X#endif
- X
- Xbrowse()
- X{
- X int c;
- X char *env;
- X
- X if(env=getenv("BROWSE"))
- X macptr = env;
- X
- X defmacs();
- X newdir();
- X redraw();
- X ended=0;
- X
- X do {
- X if(intrup) {
- X intrup=0; /* clear interrupt */
- X cmdline(); /* go to the command line */
- X outs("Interrupt"); /* let us know about it */
- X endmac(); /* clear macros */
- X clearin(); /* and input buffer */
- X }
- X here_i_am();
- X fflush(stdout);
- X c = getch();
- X cmd(c);
- X }
- X while(!ended);
- X}
- X
- Xclearin()
- X{
- X fseek(stdin, 0L, 1); /* stay here messily */
- X}
- X
- Xcmd(c)
- Xchar c;
- X{
- X int i;
- X
- X if(intrup)
- X return;
- X
- X switch(c) {
- X case ' ':
- X if(isdir(entries[curr])) {
- X if(!cd(entries[curr]->e_name))
- X wperror(entries[curr]->e_name);
- X } else
- X if(!macro(c))
- X bell();
- X else
- X cmd(getch());
- X break;
- X case '&':
- X syscom(0);
- X break;
- X case '!':
- X syscom(1);
- X break;
- X case '=':
- X todir();
- X break;
- X case '?':
- X sample(entries[curr]->e_name);
- X break;
- X case '[':
- X define();
- X break;
- X case 'B'-'@':
- X prev(nlines);
- X break;
- X case 'D'-'@':
- X next(nlines/2);
- X break;
- X case 'F'-'@':
- X next(nlines);
- X break;
- X case 'H':
- X curr=top;
- X break;
- X case 'J':
- X tail();
- X break;
- X case 'K':
- X home();
- X break;
- X case 'L'-'@':
- X redraw();
- X break;
- X case 'L':
- X curr=bottom-1;
- X break;
- X case 'M':
- X definitions();
- X break;
- X case 'N':
- X next(nlines);
- X break;
- X case 'P':
- X prev(nlines);
- X break;
- X case 'R':
- X move();
- X break;
- X case 'S':
- X savedefs();
- X break;
- X case 'U'-'@':
- X prev(nlines/2);
- X break;
- X case 'D':
- X case 'd':
- X if(getch()==c && !intrup)
- X remove(c=='D');
- X else
- X bell();
- X break;
- X case 'h':
- X ccol=0;
- X break;
- X case 'l':
- X ccol=NCOL;
- X break;
- X case '<':
- X quickmode=1;
- X if(display_up) {
- X todump=1;
- X at(0, 1);
- X header();
- X }
- X break;
- X case '+': case '^':
- X addname(c);
- X break;
- X case '(':
- X addperm();
- X break;
- X case ')':
- X delperm();
- X break;
- X case '>':
- X quickmode=0;
- X if(display_up) {
- X todump=1;
- X at(0, 1);
- X header();
- X }
- X break;
- X case 'J'-'@':
- X case 'j':
- X newline();
- X break;
- X case 'K'-'@':
- X case 'k':
- X upline();
- X break;
- X case 'n':
- X next(nlines/2);
- X break;
- X case 'p':
- X prev(nlines/2);
- X break;
- X case 'q': case 'Z': case 'Q':
- X if(getchar()==c && !intrup)
- X ended=1;
- X else
- X bell();
- X break;
- X case 'r':
- X reload();
- X break;
- X case 't':
- X tag();
- X break;
- X case 'T': case 'U':
- X tag_all(c=='T');
- X break;
- X default:
- X if(!macro(c))
- X bell();
- X else
- X cmd(getch()); /* make sure it does something */
- X } /* and thus avoid unneeded redraws */
- X}
- X
- Xcmdline()
- X{
- X at(0, li-1);
- X outs(ce);
- X}
- X
- Xnewdir()
- X{
- X if(display_up)
- X at(0,0);
- X fflush(stdout);
- X dot=pwd();
- X
- X if(!getdir())
- X wperror(dot);
- X
- X curr=0;
- X top=0;
- X topline();
- X if(display_up)
- X todump=TRUE;
- X}
- X
- Xreload()
- X{
- X getdir();
- X curr=(curr>=bottom)?bottom-1:curr;
- X if(display_up) {
- X topline();
- X todump=TRUE;
- X }
- X}
- X
- Xtopline()
- X{
- X if(display_up)
- X at(0,0);
- X printf("%s: %d files", dot, nentries);
- X nl();
- X}
- X
- Xredraw()
- X{
- X outs(cl);
- X display_up=0;
- X topline();
- X at(0,1);
- X header();
- X todump=1;
- X display_up=1;
- X}
- X
- Xdumpdata()
- X{
- X at(0,2);
- X dump(top,bottom);
- X if(top+nlines>nentries) {
- X int i;
- X at(0, bottom-top+2);
- X for(i=bottom-top; i<nlines; i++) {
- X outc('~');
- X nl();
- X }
- X }
- X}
- X
- Xupline()
- X{
- X if(curr>0)
- X curr--;
- X else bell();
- X}
- X
- Xhome()
- X{
- X curr=0;
- X}
- X
- Xnext(l)
- X{
- X curr += l;
- X if(curr>=nentries) curr=nentries-1;
- X}
- X
- Xprev(l)
- X{
- X curr -= l;
- X if(curr<0) curr=0;
- X}
- X
- Xtail()
- X{
- X curr=nentries-1;
- X}
- X
- Xnewline()
- X{
- X if(curr<nentries-1)
- X curr++;
- X else
- X bell();
- X}
- X
- Xhere_i_am()
- X{
- X int c;
- X if(*macptr)
- X return;
- X if(todump)
- X display_up = 1;
- X if(!display_up) {
- X cmdline();
- X statout(entries[curr]->e_name,
- X &entries[curr]->e_stat,
- X entries[curr]->e_uname,
- X entries[curr]->e_gname,
- X entries[curr]->e_flags);
- X at(quickmode?1:ccol, li-1);
- X fflush(stdout);
- X if((c=getch())=='\n') {
- X redraw();
- X here_i_am();
- X }
- X else
- X ungetch(c);
- X } else if(todump) {
- X if(!(curr-top > 0 && curr-top < nlines)) {
- X top = curr-nlines/2;
- X if(top<0) top=0;
- X }
- X dumpdata();
- X at(quickmode?1:ccol, curr-top+2);
- X todump=0;
- X } else {
- X int lines_to_scroll = curr-top;
- X if(lines_to_scroll > 0)
- X if((lines_to_scroll -= nlines-1) < 0)
- X lines_to_scroll = 0;
- X if(lines_to_scroll < 1-nlines) {
- X top=curr;
- X at(0,2);
- X dump(top, bottom);
- X } else if(lines_to_scroll > nlines-1) {
- X top=curr-nlines+1;
- X at(0,2);
- X dump(top, bottom);
- X } else if(lines_to_scroll) {
- X scroll(2, nlines+2, lines_to_scroll);
- X top += lines_to_scroll;
- X if(lines_to_scroll < 0) {
- X at(0, 2);
- X dump(top, top-lines_to_scroll);
- X } else {
- X at(0, 2+nlines-lines_to_scroll);
- X dump(bottom-lines_to_scroll, bottom);
- X }
- X }
- X at(quickmode?1:ccol, curr-top+2);
- X }
- X}
- X
- Xbell()
- X{
- X outc(7);
- X}
- X
- Xperform(command)
- Xchar *command;
- X{
- X char cmdbuf[MAXLINE];
- X
- X cmdline();
- X extty();
- X outc('!');
- X printf(command, entries[curr]->e_name);
- X sprintf(cmdbuf, command, entries[curr]->e_name);
- X
- X system(cmdbuf, 1);
- X entty();
- X}
- X
- Xsystem(command, rdflag)
- Xchar *command;
- Xint rdflag; /* Should I redraw? */
- X{
- X char scratch[32];
- X int status;
- X int (*sigint)(), (*sigquit)();
- X char c;
- X
- X sigint=signal(2, 1);
- X sigquit=signal(3, 1);
- X cooktty();
- X fflush(stdout);
- X strcpy(scratch, entries[curr]->e_name);
- X if(!fork()) {
- X int i;
- X static char *envp[MAXARGC];
- X static char env[NCARGS];
- X char *hold;
- X char line[MAXLINE];
- X char *tmp;
- X
- X signal(2,0);
- X signal(3,0);
- X
- X if(!(efp=fopen(efname, "r"))) {
- X fputc('\n', stderr);
- X perror(efname);
- X execl(SHELL, SHELL, "-c", command, 0);
- X execl("/bin/sh", "sh", "-c", command, 0);
- X perror("/bin/sh");
- X exit(-77);
- X }
- X
- X i=0;
- X tmp=hold=env;
- X
- X while(!feof(efp)) {
- X fgets(line, MAXLINE, efp);
- X if(strlen(line)+(tmp-env)>NCARGS)
- X break;
- X if(line[0]=='$')
- X if(tmp>hold) {
- X envp[i] = hold;
- X i++;
- X if(i > MAXARGC-2) break;
- X tmp[-1]=0; /* eat line-feed at end */
- X hold = tmp;
- X }
- X strcpy(tmp, line+(line[0]=='$'));
- X tmp += strlen(tmp);
- X }
- X if(tmp>hold) {
- X envp[i] = hold;
- X i++;
- X tmp[-1]=0; /* and eat this one as well */
- X }
- X sprintf(tmp, "FILE=%s", scratch);
- X envp[i++]=tmp;
- X envp[i]=0;
- X
- X if(rdflag)
- X putchar('\n');
- X else
- X putchar('\r');
- X fflush(stdout);
- X execle(SHELL, SHELL, "-c", command, 0, envp);
- X execle("/bin/sh", "sh", "-c", command, 0, envp);
- X perror("/bin/sh");
- X exit(-77);
- X }
- X wait(&status);
- X signal(2, sigint);
- X signal(3, sigquit);
- X rawtty();
- X
- X if(rdflag || status!=0)
- X display_up=0;
- X}
- X
- Xchar
- Xinps(buf, text, termin)
- Xchar *buf;
- Xchar *text;
- Xchar termin;
- X{
- X int i = 0;
- X char c, *ptr, *txp;
- X
- X txp=text?text:"!";
- X
- X while(!intrup &&
- X (fflush(stdout), c=getch()) != '\033' &&
- X c != '\n' &&
- X c != termin)
- X switch(c) {
- X case '\b':
- X case '\177':
- X if(i>0) {
- X printf("\b \b");
- X i--;
- X }
- X else
- X bell();
- X break;
- X case 'U'-'@':
- X txp=text?text:"!";
- X case 'X'-'@':
- X if(i>0)
- X while(i>0) {
- X printf("\b \b");
- X i--;
- X }
- X else
- X bell();
- X break;
- X case 'K'-'@':
- X if(*txp)
- X ctloutc(buf[i++] = *txp++);
- X break;
- X case '%':
- X for(ptr=entries[curr]->e_name; *ptr; ptr++)
- X ctlout(buf[i++] = *ptr);
- X standend();
- X break;
- X case '#':
- X for(ptr=dot; *ptr; ptr++)
- X ctlout(buf[i++] = *ptr);
- X standend();
- X break;
- X case '~':
- X for(ptr=HOME; *ptr; ptr++)
- X ctlout(buf[i++] = *ptr);
- X standend();
- X break;
- X case '@':
- X outc(c);
- X fflush(stdout);
- X c = getch();
- X if(!macro(c)) {
- X ungetch(c);
- X buf[i++]='@';
- X }
- X else
- X outs("\b \b");
- X break;
- X case '$':
- X outc(c);
- X fflush(stdout);
- X c = getch();
- X if(c=='$') {
- X char tmp[10];
- X sprintf(tmp, "%d", getpid());
- X outs("\b \b");
- X for(ptr=tmp; *ptr; ptr++)
- X ctlout(buf[i++] = *ptr);
- X standend();
- X }
- X else if(!macbuf[c]) {
- X ungetch(c);
- X buf[i++]='$';
- X }
- X else {
- X outs("\b \b");
- X for(ptr=macbuf[c]; *ptr; ptr++)
- X ctlout(buf[i++] = *ptr);
- X standend();
- X }
- X break;
- X case '!':
- X while(*txp)
- X ctlout(buf[i++] = *txp++);
- X standend();
- X break;
- X case '\\':
- X outc(c);
- X fflush(stdout);
- X c=getch();
- X if(c=='~' || c=='%' || c=='#' ||
- X c=='\\' || c=='!' ||
- X c=='K'-'@' || c=='U'-'@' || c=='X'-'@' ||
- X c=='\b' || c=='\177' ||
- X c==termin || c=='\033' || c=='\n' ||
- X c=='@' || c=='$') {
- X outc('\b');
- X ctloutc(buf[i++]=c);
- X break;
- X }
- X else if(c>='0' && c<='7') {
- X int n, val=0;
- X for(n=0; n<3 && c>='0' && c<='7'; n++) {
- X val = val*8 + c-'0';
- X outc('\b');
- X ctloutc(val);
- X c=getch();
- X }
- X ungetch(c);
- X c=buf[i++]=val;
- X break;
- X }
- X else if(c=='^') {
- X outc('\b');
- X outc('^');
- X fflush(stdout);
- X c=getch();
- X if(c>='?'&&c<='_') {
- X outc('\b');
- X ctloutc(buf[i++]=(c-'@')&'\177');
- X break;
- X }
- X else if(c>='`'&&c<='~') {
- X outc('\b');
- X ctloutc(buf[i++]=c-'`');
- X break;
- X } /* otherwise default */
- X else buf[i++]='^'; /* after adding caret */
- X
- X } /* otherwise fall through to default */
- X else buf[i++]='\\'; /* after adding backslash */
- X default:
- X ctloutc(buf[i++] = c);
- X break;
- X }
- X
- X buf[i] = 0;
- X return intrup?'\033':c;
- X}
- X
- Xctlouts(s)
- Xchar *s;
- X{
- X int cnt = 0;
- X
- X while(*s)
- X cnt += ctlout(*s++);
- X cnt += standend();
- X
- X return cnt;
- X}
- X
- Xctloutc(c)
- Xchar c;
- X{
- X int cnt;
- X
- X cnt = ctlout(c);
- X cnt += standend();
- X
- X return cnt;
- X}
- X
- Xint somode = 0;
- Xint ulmode = 0;
- X
- Xstandout()
- X{
- X if(!somode) {
- X outs(so);
- X somode = 1;
- X if(xn) return 1;
- X }
- X return 0;
- X}
- X
- Xunderline()
- X{
- X if(!ulmode) {
- X outs(us);
- X ulmode = 1;
- X if(xn) return 1;
- X }
- X return 0;
- X}
- X
- Xstandend()
- X{
- X int cnt = 0;
- X
- X if(somode) {
- X outs(se);
- X somode = 0;
- X if(xn) cnt++;
- X }
- X if(ulmode) {
- X outs(ue);
- X ulmode = 0;
- X if(xn) cnt++;
- X }
- X return cnt;
- X}
- X
- Xctlout(c)
- Xchar c;
- X{
- X int cnt = 0;
- X if(c&'\200') {
- X cnt += underline();
- X cnt += ctlout(c&'\177');
- X return cnt;
- X }
- X else if(c<' ' || c=='\177') {
- X cnt += standout();
- X outc((c+'@')&'\177');
- X cnt++;
- X return cnt;
- X }
- X else {
- X cnt += standend();
- X outc(c);
- X cnt++;
- X return cnt;
- X }
- X}
- X
- Xtodir()
- X{
- X char cmdbuf[MAXLINE];
- X static char lastdir[MAXLINE] = ".";
- X char *slash, *rindex();
- X
- X cmdline();
- X printf("goto ");
- X if(inps(cmdbuf, lastdir, 0)!='\033' && cmdbuf[0]) {
- X strcpy(lastdir, cmdbuf);
- X if(!cd(cmdbuf, 0)) {
- X if(!fgoto(cmdbuf))
- X if(slash=rindex(cmdbuf, '/')) {
- X *slash++=0;
- X if(cd(cmdbuf, 1)) {
- X if(!fgoto(slash)) {
- X errno=0;
- X xerrno=NOMATCH;
- X wperror(slash);
- X }
- X } else
- X wperror(cmdbuf);
- X } else
- X wperror(cmdbuf);
- X }
- X }
- X else
- X killcmd();
- X}
- X
- Xfgoto(file)
- Xchar *file;
- X{
- X int i;
- X
- X for(i = 0; i<nentries; i++)
- X if(match(entries[i]->e_name, file)) {
- X curr=i;
- X return 1;
- X }
- X
- X return 0;
- X}
- X
- Xmatch(target, sample)
- Xchar *target, *sample;
- X{
- X while(*sample && *target==*sample) {
- X target++;
- X sample++;
- X }
- X return !*sample;
- X}
- X
- Xkillcmd()
- X{
- X if(!intrup) {
- X cmdline();
- X printf("Command killed");
- X if(!display_up)
- X nl();
- X }
- X}
- X
- Xcd(dir, flag)
- Xchar *dir;
- Xint flag;
- X{
- X if(flag) {
- X cmdline();
- X printf("cd %s\r", dir);
- X }
- X else
- X outc('\r');
- X fflush(stdout);
- X if(access(dir, 5)==0 && chdir(dir)==0) {
- X newdir();
- X return 1;
- X }
- X return 0;
- X}
- X
- Xsyscom(rd)
- Xint rd; /* should I redraw? */
- X{
- X char buf[MAXLINE];
- X static char lastcmd[MAXLINE] = "";
- X char inps();
- X
- X cmdline();
- X extty();
- X putchar(rd?'!':'&');
- X if(inps(buf, lastcmd, 0)=='\033') {
- X entty();
- X killcmd();
- X return;
- X }
- X else
- X strcpy(lastcmd, buf);
- X system(buf, rd);
- X entty();
- X}
- X
- Xisdir(entry)
- Xstruct entry *entry;
- X{
- X return((entry->e_stat.st_mode&S_IFMT)==S_IFDIR);
- X}
- X
- Xsample(name)
- Xchar *name;
- X{
- X int col;
- X int c, i;
- X FILE *tfp;
- X
- X if(!(tfp = fopen(name, "r"))) {
- X wperror(name);
- X return;
- X }
- X
- X i=0;
- X do {
- X cmdline();
- X col = 0;
- X for(c=fgetc(tfp); col<72 && !feof(tfp); c=fgetc(tfp))
- X col+=ctlout(c);
- X standend();
- X if(display_up)
- X outc('\r');
- X else
- X outc('\n');
- X }
- X while(!feof(tfp) && (i=getch())=='?');
- X
- X fclose(tfp);
- X
- X if(i && i!=' ' && i!='q' && i!='?')
- X ungetch(i);
- X}
- X
- Xmacro(c)
- Xchar c;
- X{
- X if(c==NOMAC)
- X return 0;
- X else if(!macbuf[c])
- X return 0;
- X else if(c==c_macro) {
- X cmdline();
- X printf("Recursive macro.");
- X endmac();
- X return 0;
- X }
- X else {
- X c_macro = c;
- X macptr = macbuf[c];
- X return 1;
- X }
- X}
- X
- Xgetch()
- X{
- X char c;
- X
- X if(ungetptr>ungetbuf)
- X return *--ungetptr;
- X if(*macptr)
- X if(*macptr=='\007') {
- X macptr++;
- X if(*macptr!='\007')
- X return getchar();
- X else {
- X if((c=getchar()) != '\n')
- X macptr--;
- X else
- X macptr++;
- X return (c=='\n')?getch():c;
- X }
- X }
- X else if(*macptr=='\\') {
- X if(macptr[1]=='\007')
- X macptr++;
- X return *macptr++;
- X }
- X else
- X return *macptr++;
- X else {
- X endmac();
- X return getchar();
- X }
- X}
- X
- Xendmac() {
- X c_macro=NOMAC;
- X macptr="";
- X}
- X
- Xungetch(c)
- Xchar c;
- X{
- X if(ungetptr-ungetbuf>SMALLBUF)
- X return;
- X *ungetptr++=c;
- X}
- X
- Xdefine()
- X{
- X int c;
- X char buf[SMALLBUF];
- X
- X cmdline();
- X
- X printf("define ");
- X c = getch();
- X
- X if(intrup)
- X return;
- X
- X ctloutc(c);
- X printf(" as [");
- X if(inps(buf, macbuf[c], ']')=='\033') {
- X killcmd();
- X return;
- X }
- X printf("]");
- X
- X defent(c, buf);
- X}
- X
- Xdefent(c, buf)
- Xchar c;
- Xchar *buf;
- X{
- X if(macbuf[c])
- X free(macbuf[c]);
- X
- X if(!buf[0]) {
- X macbuf[c]=0;
- X return;
- X }
- X
- X macbuf[c] = (char *)malloc(strlen(buf)+1);
- X
- X if(!macbuf[c]) {
- X cmdline();
- X printf("No room");
- X return;
- X }
- X
- X strcpy(macbuf[c], buf);
- X}
- X
- Xdefmacs()
- X{
- X defent(' ', "!more %\n");
- X defent('%', "!%\n");
- X defent('.', "=.");
- X defent('/', "=/");
- X defent('~', "=~");
- X defent('v', "!vi %\n");
- X defent('$', "!vi /tmp/br.env.$$\n");
- X}
- X
- Xdefinitions()
- X{
- X char *ptr;
- X int i;
- X
- X cmdline();
- X for(i=0; i<CHARSET; i++)
- X if(macbuf[i]) {
- X printf("define ");
- X ctloutc(i);
- X printf(" as [");
- X ctlouts(macbuf[i]);
- X printf("]\n");
- X }
- X display_up=0;
- X}
- X
- Xsavedefs()
- X{
- X int i;
- X char filename[MAXLINE];
- X static char lastfile[MAXLINE] = "/usr/tmp/macros";
- X FILE *fp;
- X
- X cmdline();
- X outs("Save macros as ");
- X
- X if(inps(filename, lastfile, '\033')=='\033') {
- X killcmd();
- X return;
- X }
- X
- X strcpy(lastfile, filename);
- X
- X if(!(fp = fopen(filename, "w"))) {
- X wperror(filename);
- X return;
- X }
- X
- X for(i=1; i<CHARSET; i++)
- X if(macbuf[i])
- X fprintf(fp, "[%c%s]\n", i, macbuf[i]);
- X
- X fclose(fp);
- X}
- X
- Xdumpenv(envp)
- Xchar **envp;
- X{
- X if(!(efp=fopen(efname, "w"))) {
- X fperror(efname);
- X exit(-1);
- X }
- X while(*envp)
- X fprintf(efp, "$%s\n", *envp++);
- X fflush(efp);
- X}
- //END_OF_FILE
- echo "End of archive."
- # end of archive.
- exit 0
-
-
-